<script setup lang="ts">
import {computed, nextTick, ref} from 'vue'
import type { SpuData, AllTrademark,  AllSpuImg, SaleAttrResponseData, AllSaleAttrResponseData,
    TradeMark, SpuImg, SaleAttr, AllSaleAttr, SaleAttrValue
 } from '@/network/product/spu/type';
import { allTrademarkAPI, spuImageAPI, hasSaleAttrAPI, allSaleAttrAPI, AddOrUpdateSpu } from '@/network/product/spu';
import { ElMessage } from 'element-plus';
const emit = defineEmits(['changeIsShow'])
// 取消通知父组件，切换为场景0
function cancel() {
    emit('changeIsShow', {
            params:  ''
        })
} 

// 存储已有的spu数据
const allTrademark = ref<TradeMark[]>([])
const imgList = ref<SpuImg[]>([])
const hasSaleList = ref<SaleAttr[]>([])
const allSaleList = ref<AllSaleAttr[]>([])
// 存储已有的spu对象

const spuParams = ref<SpuData>({
    category3Id: 0, // 三级分类id
    spuName: '', // spu名字
    description: '', // spu描述
    tmId: '', // 品牌id
    spuImageList: [],
    spuSaleAttrList: []
})
// 请求全部子组件要展示的数据
const initHasSpuData = async (spu: SpuData) => {
    // spuParams.value = spu
    // 需要深复制，避免两个对象互相影响
    Object.assign(spuParams.value, JSON.parse(JSON.stringify(spu)))
    
    // spu即为父组件传过来的已有的spu对象(不完整)
    // console.log(spu);
    // 获取全部品牌名称的数据
    const res1 :AllTrademark = await allTrademarkAPI()
    // console.log(res1);
    // spu下全部售卖商品的图片
    const res2: AllSpuImg = await spuImageAPI(spu.id)
    // console.log(res2);
    //  spu已有的销售属性
    const res3: SaleAttrResponseData = await hasSaleAttrAPI(spu.id)
    // console.log(res3);
    // 获取全部销售属性
    const res4: AllSaleAttrResponseData = await allSaleAttrAPI()
    // console.log(res4);
    allTrademark.value = res1.data
    // 由于element-plus 预览框要的字段必须是如下
    imgList.value = res2.data.map(item => {
        return {
            name: item.imgName,
            url: item.imgUrl
        }
    })
    hasSaleList.value = res3.data
    allSaleList.value = res4.data
}



// 弹出预览框
const dialogVisible = ref<boolean>(false)
// 点击预览存储图片
const dialogImageUrl = ref<string>('')
// 图片预览钩子
function handlePictureCardPreview(file: any) {
    console.log(file);
    dialogImageUrl.value = file.url
    dialogVisible.value = true
}

// 删除图片
function handleRemove() {
    console.log('删除图片');
}
// 上传图片之前触发的钩子: 限制用户上传图片格式与大小
function beforeAvatarUpload(file: any) {
    // console.log(file);
    if (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif') {
        if (file.size / 1024 / 1024 > 3) {
            ElMessage({
            type: 'error',
            message: '上传文件应小于3M'
            })
            return false
        }
        return true
    } else {
        ElMessage({
            type: 'error',
            message: '上传文件格式为jpeg|png|gif格式'
        })
        return false
    }
}


// 计算当前spu还未拥有的销售属性
const unSelectSaleAttr = computed(() => {
   return allSaleList.value.filter(item => {
        return hasSaleList.value.every(item1 => {
            return item.name !== item1.saleAttrName
        })
    })
})

// 收集未选择的销售属性的id与属性的名字
const noSaleAttrIdAndSaleAttrName = ref<string>('')

// 添加销售属性
function addSaleAttr() {
    const arr = noSaleAttrIdAndSaleAttrName.value.split(':')
    // console.log(arr);
    const [baseSaleAttrId, saleAttrName] = arr
    const newSaleAttr: SaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: [],
    }
    hasSaleList.value.push(newSaleAttr) 
    // 清空收集的数据
    noSaleAttrIdAndSaleAttrName.value = ''
}

// 添加属性值
function toEdit(row: SaleAttr) {
    row.flag = true
    // 多添加一个属性值名字
    row.saleAttrValueName = ''
    // DOM刚渲染拿不到数据
    nextTick(() => {
        inputArr.value.focus()
    })
    
}

// 文本框失焦
function inputBlur(row: SaleAttr) {
    // console.log(row);
    const {saleAttrValueName, baseSaleAttrId} = row
    
    // 整理成服务器需要的属性值格式
    const newSaleAttrValue: SaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName
    }
    // 非法情况1：不能为空
    if (!saleAttrValueName.trim()) {
        // hasSaleList.value.splice($index, 1)
        
        ElMessage({
            type: 'error',
            message: '属性值不能为空'
        })
        return 
    }

    // 2. 情况二：属性值不能重复
   const repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName === saleAttrValueName
    })
    // console.log(repeat);
    if (repeat) {
        ElMessage({
            type: 'error',
            message: '属性值不能重复'
        })
        return
    }

    row.spuSaleAttrValueList.push(newSaleAttrValue)
    // 显示button
    row.flag = false
}

// 准备一个数组，存储对应的组件实例el-input
const inputArr = ref<any>({})


// 保存
async function save() {
    // console.log(999);
    // 1. 整理数据，发请求更新数据
    // 2. 照片墙数据
    // 改成服务器需要的名字和地址格式
    spuParams.value.spuImageList = imgList.value.map((item) => {
        return {
            imgName: item.name,
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    // console.log(spuParams.value.spuImageList);
    // 3. 整理销售属性的数据
    spuParams.value.spuSaleAttrList = hasSaleList.value
    // 4. 发请求
    const res = await AddOrUpdateSpu(spuParams.value)
    console.log(res);
    if (res.code === 200) {
        ElMessage({
            type: 'success',
            message: spuParams.value.id ? '修改成功' : '添加成功'
        })
        // 修改成功返回spu主界面
        emit('changeIsShow', {
            params: spuParams.value.id ? 'update' : 'add'
        })
    } else {
        ElMessage({
            type: 'error',
            message: spuParams.value.id ? '修改失败' : '添加失败'
        })
    }
}

// 添加spu初始化方法
const initAddSpu = async (c3Id: number) => {
    // 清空数据先
    // 如果先修改，会遗留id 再次添加时，需要删除，避免影响后续判断
    delete spuParams.value.id
    Object.assign(spuParams.value, {
    // id: 0,
    category3Id: 0, // 三级分类id
    spuName: '', // spu名字
    description: '', // spu描述
    tmId: '', // 品牌id
    spuImageList: [],
    spuSaleAttrList: []
})
// 图片和属性都需要清
imgList.value = []
hasSaleList.value = []
noSaleAttrIdAndSaleAttrName.value = ''
    // 存储三级分类id
    spuParams.value.category3Id = c3Id
    const res1 :AllTrademark = await allTrademarkAPI()
    const res2: AllSaleAttrResponseData = await allSaleAttrAPI()
    // 存储数据
    allTrademark.value = res1.data
    allSaleList.value = res2.data
}

defineExpose({
    initHasSpuData,
    initAddSpu
})

</script>


<template>
    <el-form label-width="120px">
        <el-form-item style="width: 30%;" label="spu名称">
            <el-input v-model="spuParams.spuName" placeholder="请输入spu名称"></el-input>
        </el-form-item>
        <el-form-item style="width: 30%;" label="品牌名称">
            <el-select v-model="spuParams.tmId" placeholder="请选择品牌名称">
                <el-option v-for="item,index in allTrademark" :value="item.id" :key="item.id" :label="item.tmName" ></el-option>
            </el-select>
        </el-form-item>
        <el-form-item style="width: 50%;" label="spu描述">
            <el-input v-model="spuParams.description" type="textarea" placeholder="请输入spu描述"></el-input>
        </el-form-item>
        <el-form-item label="spu图标">
            <!-- 
                1. v-model:file-list 默认展示图片
                2. action上传服务器图片，得写/api 否则代理服务器不发送这次post请求
                3. list-type图片文件列表的类型
                4. on-preview点击图片预览的钩子
             -->
            <el-upload
                v-model:file-list="imgList"
                action="/api/admin/product/fileUpload"
                list-type="picture-card"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemove"
                :before-upload="beforeAvatarUpload">
                <el-icon><Plus /></el-icon>
            </el-upload>
            <el-dialog v-model="dialogVisible">
                <img w-full :src="dialogImageUrl" alt="Preview Image" />
            </el-dialog>
        </el-form-item>
        <el-form-item  label="spu销售属性">
            <el-select v-model="noSaleAttrIdAndSaleAttrName" :placeholder="unSelectSaleAttr.length ? `还有${unSelectSaleAttr.length}条未选择`: '无可选属性'" style="width: 30%; margin-right: 10px;">
                <el-option v-for="item, index in unSelectSaleAttr" :value="`${item.id}:${item.name}`" :label="item.name"  :key="item.id"></el-option>
            </el-select>
            <el-button @click="addSaleAttr" :disabled="noSaleAttrIdAndSaleAttrName ? false : true" type="primary" icon="Plus">添加销售属性</el-button>
            <el-table border style="margin: 20px 0;" :data="hasSaleList">
                <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
                <el-table-column label="销售属性名字" prop="saleAttrName" width="120px"></el-table-column>
                <el-table-column label="销售属性值">
                    <template #="{row, $index}">
                        <el-tag @close="row.spuSaleAttrValueList.splice(index, 1)" v-for="item,index in row.spuSaleAttrValueList" closable :key="item.id" style="margin: 5px;">{{ item.saleAttrValueName }}</el-tag>
                        <el-input :ref="(vc: any) => inputArr = vc" v-model="row.saleAttrValueName" @blur="inputBlur(row)" v-if="row.flag" placeholder="请输入属性值" size="small" style="width: 100px;"></el-input>
                        <el-button @click="toEdit(row)" v-else type="primary" size="small" icon="Plus"></el-button>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="120px">
                    <template #="{row, $index}">
                        <el-button @click="hasSaleList.splice($index, 1)" type="danger" size="small" icon="Delete"></el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button :disabled="!hasSaleList.length" @click="save" type="primary">保存</el-button>
            <el-button type="primary" @click="cancel">取消</el-button>
        </el-form-item>
    </el-form>
</template>


<style scoped lang='scss'>

</style>
